<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>橡皮擦笔刷 EraserBrush</title>
  </head>
  <body>
    <div style="margin-bottom: 10px">
      <button id="erase" type="button" onclick="changeAction('erase')">
        擦拭
      </button>
      <button id="erase" type="button" onclick="changeAction('undoErasing')">
        恢复擦拭
      </button>
      <button onclick="quanxuan()">圈选</button>
      <button onclick="undo()">撤销</button>
      <button onclick="redo()">重做</button>
    </div>
    <canvas
      id="c"
      width="400"
      height="400"
      style="border: 1px solid #ccc"
    ></canvas>

    <script src="./xpc/fabric.js"></script>
    <script src="./fabric-history.js"></script>
    <script>
      const canvas = new fabric.Canvas("c", {
        isDrawingMode: true,
      });
      canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);
      canvas.freeDrawingBrush.width = 10;

      canvas.on("mouse:up", function (options) {
        if (isQuanxuan) {
          onAttemptAutoFill();
        }
      });

      // 修改画板行为模式
      function changeAction(mode) {
        switch (mode) {
          case "select":
            canvas.isDrawingMode = false; // 不允许绘画（返回普通框选模式）
            break;
          case "erase":
            canvas.isDrawingMode = true; // 进入绘画模式
            canvas.freeDrawingBrush = new fabric.EraserBrush(canvas); // 使用橡皮擦画笔
            canvas.freeDrawingBrush.width = 10; // 设置画笔粗细为 10
            break;
          case "undoErasing":
            canvas.isDrawingMode = true;
            canvas.freeDrawingBrush = new fabric.EraserBrush(canvas);
            canvas.freeDrawingBrush.width = 10;
            canvas.freeDrawingBrush.inverted = true;
          default:
            break;
        }
      }
      let isQuanxuan = false;
      function quanxuan() {
        isQuanxuan = true;
        canvas.freeDrawingBrush.width = 2;
      }

      function undo() {
        canvas.undo();
      }
      function redo() {
        canvas.redo();
      }

      //  填充图形 圈选
      function onAttemptAutoFill() {
        // 获取最后绘制的路径
        const lastPath = canvas.getObjects().slice(-1)[0];
        // 确保是路径对象
        if (lastPath && lastPath.type === "path") {
          const pathCoords = lastPath.path;

          // 至少需要4个点（起点+3个其他点）
          if (pathCoords.length >= 4) {
            const firstPoint = { x: pathCoords[0][1], y: pathCoords[0][2] };
            const lastPoint = {
              x: pathCoords[pathCoords.length - 1][1],
              y: pathCoords[pathCoords.length - 1][2],
            };

            // 计算路径总长度
            let totalLength = 0;
            for (let i = 1; i < pathCoords.length; i++) {
              const dx = pathCoords[i][1] - pathCoords[i - 1][1];
              const dy = pathCoords[i][2] - pathCoords[i - 1][2];
              totalLength += Math.sqrt(dx * dx + dy * dy);
            }

            // 计算起点和终点的距离
            const startEndDistance = Math.sqrt(
              Math.pow(lastPoint.x - firstPoint.x, 2) +
                Math.pow(lastPoint.y - firstPoint.y, 2)
            );

            // 计算"开放度"：起点终点距离占总路径长度的百分比
            const openness = (startEndDistance / totalLength) * 100;

            // 如果开放度小于阈值，认为可以自动闭合
            if (openness < 100) {
              // 获取路径边界框
              const bounds = lastPath.getBoundingRect();

              // 创建填充多边形，包含自动闭合线段
              const points = [];
              for (let i = 0; i < pathCoords.length; i++) {
                const p = new fabric.Point(pathCoords[i][1], pathCoords[i][2]);
                const transformedPoint = fabric.util.transformPoint(
                  p,
                  lastPath.calcTransformMatrix()
                );
                points.push({
                  x: transformedPoint.x - bounds.left,
                  y: transformedPoint.y - bounds.top,
                });
              }

              // 添加从终点到起点的闭合线段
              const startPointTransformed = fabric.util.transformPoint(
                new fabric.Point(firstPoint.x, firstPoint.y),
                lastPath.calcTransformMatrix()
              );
              points.push({
                x: startPointTransformed.x - bounds.left,
                y: startPointTransformed.y - bounds.top,
              });

              // 创建多边形并设置与原路径相同的位置和变换
              const polygon = new fabric.Polygon(points, {
                left: bounds.left,
                top: bounds.top,
                fill: "#000000",
                stroke: null,
                selectable: false,
                angle: lastPath.angle,
                scaleX: lastPath.scaleX,
                scaleY: lastPath.scaleY,
                originMode: "selection", // 标记为圈选模式创建的对象
              });

              canvas.add(polygon);
              canvas.renderAll();
              console.log(`区域已自动填充 (开放度: ${openness.toFixed(1)}%)`);
            } else {
              console.log(
                `图形开放度太大 (${openness.toFixed(
                  1
                )}%)，请继续绘制或调整闭合阈值。`,
                "warning"
              );
            }
          } else {
            console.log("图形未闭合，请继续绘制或重新开始。", "warning");
          }
        } else {
          console.log("请先绘制封闭图形。", "warning");
        }
      }
    </script>
  </body>
</html>
